package org.dromara.common.mybatis.aspect

import io.github.oshai.kotlinlogging.KotlinLogging
import org.aopalliance.intercept.MethodInterceptor
import org.aopalliance.intercept.MethodInvocation
import org.dromara.common.mybatis.annotation.DataPermission
import org.dromara.common.mybatis.helper.DataPermissionHelper
import java.lang.reflect.Method
import java.lang.reflect.Proxy

/**
 * 数据权限注解Advice
 *
 * @author LikeYouDo
 */
open class DataPermissionAdvice : MethodInterceptor {
    companion object{
        private val log = KotlinLogging.logger { }
    }
    @Throws(Throwable::class)
    override fun invoke(invocation: MethodInvocation): Any? {
        val target = invocation.getThis()
        val method = invocation.method
        val args = invocation.arguments
        // 设置权限注解
        DataPermissionHelper.setPermission(getDataPermissionAnnotation(target!!, method, args))
        try {
            // 执行代理方法
            return invocation.proceed()
        } finally {
            // 清除权限注解
            DataPermissionHelper.removePermission()
        }
    }

    /**
     * 获取数据权限注解
     */
    private fun getDataPermissionAnnotation(target: Any, method: Method, args: Array<Any>?): DataPermission? {
        var dataPermission = method.getAnnotation(DataPermission::class.java)
        // 优先获取方法上的注解
        if (dataPermission != null) {
            return dataPermission
        }
        // 方法上没有注解，则获取类上的注解
        var targetClass: Class<*> = target.javaClass
        // 如果是 JDK 动态代理，则获取真实的Class实例
        if (Proxy.isProxyClass(targetClass)) {
            targetClass = targetClass.interfaces[0]
        }
        dataPermission = targetClass.getAnnotation(DataPermission::class.java)
        return dataPermission
    }
}
